/*
 * 文件名称 : ByteConvert.java
 * <p>
 * 作者信息 : liuzongyao
 * <p>
 * 创建时间 : 2013-9-10, 下午7:34:24
 * <p>
 * 版权声明 : Copyright (c) 2009-2012 Hydb Ltd. All rights reserved
 * <p>
 * 评审记录 :
 * <p>
 */

package com.alan.libapi.utils;

import android.util.Log;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 请在这里增加文件描述
 * <p>
 */
public class ConvertUtil {
	
    // 产品要求单位都使用一个字节
    private static final long BASE_B = 1L; // 转换为字节基数
    private static final long BASE_KB = 1024; // 转换为KB
    private static final long BASE_MB = 1024 * 1024; // 转换为M的基数
    private static final long BASE_GB = 1024 * 1024 * 1024;
    private static final long BASE_TB = 1024L * 1024L * 1024L * 1024L;
    
    public static final String UNIT_BIT = "B";
    public static final String UNIT_KB = "KB";
    public static final String UNIT_MB = "MB";
    public static final String UNIT_GB = "GB";
    public static final String UNIT_TB = "TB";
    
    public static String byteConvert(long byteNum) {
        double tmp = byteNum / (1000 * 1024 * 1024 * 1.0);
        double f;
        String res;
        if (tmp >= 1.0) {
            // 大于等于1000M 用G表示
            f = byteNum / (1024 * 1024 * 1024 * 1.0);
            BigDecimal b = new BigDecimal(f);
            double doubleRes = b.setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
            res = Double.toString(doubleRes) + "GB";
        } else {
            // 小于1000M
            tmp = byteNum / (1000 * 1024 * 1.0);
            if (tmp >= 1.0) {
                // 大于等于1000K
                f = byteNum / (1024 * 1024 * 1.0);
                BigDecimal b = new BigDecimal(f);
                double doubleRes = b.setScale(1, BigDecimal.ROUND_DOWN).doubleValue();
				res = Double.toString(doubleRes) + "MB";
			} else {
				// 小于1M
				tmp = byteNum / (1000 * 1.0);
				if (tmp >= 1.0) {
					// 大于等于1000B
					f = byteNum / (1024 * 1.0);
					BigDecimal b = new BigDecimal(f);
					double doubleRes = b.setScale(1, BigDecimal.ROUND_DOWN).doubleValue();
					res = Double.toString(doubleRes) + "KB";
				} else {
					// 小于1000B
					res = byteNum + "B";
				}
			}
		}
		return res;
    }
    


	public static String byteConvert(long byteNum, boolean trim) {
		String res = byteConvert(byteNum);
		if (trim) {
			if (res.length() >= 7) {
				String original = res;
				res = original.substring(0, 4);
				if (res.endsWith(".")) {
					res = res.substring(0, 3);
				}
				res = res + original.substring(original.length() - 2, original.length());
			}
		}
		return res;
	}
    
	/**
	 * 获取文件长度的智能可读字符串形式。
	 * 
	 * @param size
	 *            文件字节长度
	 * @return 文件长度的字符串表示
	 */
	public static String byteConvertSize(long size) {
		if (size < 1024)
			return String.format("%d B", size);
		else if (size < 1024 * 1024)
			return String.format("%.2f KB", (double) size / 1024);
		else if (size < 1024 * 1024 * 1024)
			return String.format("%.2f MB", (double) size / (1024 * 1024));
		else if (size < 1024L * 1024 * 1024 * 1024)
			return String.format("%.2f GB", (double) size
					/ (1024 * 1024 * 1024));
		else
			return String.format("%.2f EB", (double) size
					/ (1024L * 1024 * 1024 * 1024));
	}
	/**
	 * 从文件长度的字符串形式转换为字节数表示。
	 * 
	 * @param sizeString
	 *            文件长度的字符串表示
	 * @return 文件字节长度
	 * @throws ParseException
	 *             给定字符串不是支持的形式，解析失败
	 */
	public static long stringToSize(String sizeString) throws ParseException {
		Pattern pattern = Pattern.compile("(-?\\d+\\.?\\d*)([\\w]{0,2})",
				Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(sizeString);
		if (matcher.matches()) {
			double baseSize = Double.parseDouble(matcher.group(1));
			String unit = matcher.group(2).toLowerCase();
			if (unit.equalsIgnoreCase("b") || unit.length() == 0) {
				return (long) baseSize;
			} else if (unit.equalsIgnoreCase("k") || unit.equalsIgnoreCase("kb")) {
				return (long) (baseSize * 1024);
			} else if (unit.equalsIgnoreCase("m") || unit.equalsIgnoreCase("mb")) {
				return (long) (baseSize * (1024 * 1024));
			} else if (unit.equalsIgnoreCase("g") || unit.equalsIgnoreCase("gb")) {
				return (long) (baseSize * (1024 * 1024 * 1024));
			} else if (unit.equalsIgnoreCase("e") || unit.equalsIgnoreCase("eb")) {
				return (long) (baseSize * (1024L * 1024 * 1024 * 1024));
			}
		}
		throw new ParseException(sizeString, 0);
	}	
	
	/**
	 * 从时间跨度的字符串形式转换为毫秒数表示。
	 * 
	 * @param timeString
	 *            时间跨度的字符串表示
	 * @return 毫秒数
	 * @throws ParseException
	 *             给定字符串不是支持的形式，解析失败
	 */
	public static long timespanToMillis(String timeString)
			throws ParseException {
		Pattern pattern = Pattern.compile("(-?\\d+\\.?\\d*)([\\w]{0,1})",
				Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(timeString);
		if (matcher.matches()) {
			double baseMillis = Double.parseDouble(matcher.group(1));
			String unit = matcher.group(2).toLowerCase();
			if (unit.equals("d") || unit.length() == 0) {
				return (long) (baseMillis * 1000 * 3600 * 24);
			} else if (unit.equals("h")) {
				return (long) (baseMillis * 1000 * 3600);
			} else if (unit.equals("w")) {
				return (long) (baseMillis * 1000 * 3600 * 24 * 7);
			} else if (unit.equals("m")) {
				return (long) (baseMillis * 1000 * 3600 * 24 * 30);
			} else if (unit.equals("y")) {
				return (long) (baseMillis * 1000 * 3600 * 24 * 360);
			}
		}
		throw new ParseException(timeString, 0);
	}

	
    /**
     * 通过等级，算升级所需的经验值
     * 
     * @param level
     * @return
     */
    public static int levelToScore(int level) {
        return 50 * (level + 1) * (level + 4);
    }
    
    /**
     * 通过当前经验值算等级
     * 
     * @param score
     * @return
     */
    public static int scoreToLevel(int score) {
        int rank = 0;

        while (true) {
            if (score < 50 * rank * (rank + 3))
                break;
            rank += 1;
        }

        return rank > 1 ? rank - 1 : 0;
    }

    
    public static long stringToLong(String string) {
        long value = 0;
        try {
            value = Long.valueOf(string);
        } catch (Exception e) {
            Log.e("stringToLong", "get invalid params, string = " + string);
            value = 0;
        }
        return value;
    }

    public static int stringToInt(String string) {
        int value = 0;
        try {
            value = Integer.valueOf(string);
        } catch (Exception e) {
        	Log.e("stringToInt", "get invalid params, string = " + string);
            value = 0;
        }
        return value;
    }
    
    /**
     * 将String类型的IP地址转换成int32类型。将192.168.11.101转换为1812703424 注：int32 高位在前，地位在后
     * 
     * @param IPAddress
     *            String类型的IP地址，如：192.168.11.101
     * @return int32类型的IP地址，如：1812703424, 如果IPAddress为null或者不合法，则返回0
     */
    public static int ipAddrToInt(String IPAddress) {
        if (null == IPAddress) {
            // throw new NullPointerException("IPAddress is null.");
            // NullPointerException 如果IPAddress为null
            return 0;
        }
        if (!IPAddress
                .matches("^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$")) {
            // throw new
            // RuntimeException("IPAddress is not valid...");RuntimeException
            // 如果String类型的IP地址格式不合法。
            return 0;
        }
        String[] array = IPAddress.split("\\.");
        int a = Integer.parseInt(array[0]);
        int b = Integer.parseInt(array[1]) << 8;
        int c = Integer.parseInt(array[2]) << 16;
        int d = Integer.parseInt(array[3]) << 24;
        return a | b | c | d;
    }
    
    
    /**
     * 速度转为字符串
     * 
     * @param speed
     *            速度，以B为单位
     * @param precision
     *            保留小数点位数
     * @return String[2] 其中ret[0]是数字 ret[1]是单位
     */
    public static String[] convertSpeeds(long speed, int precision) {
        String[] ret = new String[2];
        String str = convertFileSize(speed, 0);
        // 单位是一个字节
        String unit = str.substring(str.length() - 1);
        ret[0] = str.substring(0, str.lastIndexOf(unit));
        // ret[1] = unit + "/s";
        // 调整单位格式统一设置为B/s、KB/s、MB/s、GB/s
        if (unit.equals(UNIT_BIT)) {
            ret[1] = unit + "/s";
        } else {
            ret[1] = unit + "B/s";
        }

        return ret;
    }

    /**
     * 小数转换为百分值
     * 
     * @param value
     *            待转换
     * @param scale
     *            小数位数 10.1% 10.01%
     * @param zeroStr
     *            0的返回值
     * @return e.g. 10.5
     */
    public static String convertPercent(float value, int scale, String zeroStr) {
        BigDecimal b = new BigDecimal(value * 100);
        value = b.divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP).floatValue();
        if (Float.compare(value, (float) Math.pow(10, -scale)) < 0) {
            return zeroStr;
        } else {
            return String.valueOf(value);
        }
    }

    public static String convertFileSize(long file_size, int precision) {
        long int_part = 0;
        double fileSize = file_size;
        double floatSize = 0L;
        long temp = file_size;
        int i = 0;
        long base = 1L;
        String baseUnit = "M";
        String fileSizeStr = null;
        int indexMid = 0;

        while (temp / 1024 > 0) {
            int_part = temp / 1024;
            temp = int_part;
            i++;
            if (i == 4){
            	break;
            }
        }

        switch (i) {
        case 0:	// B
            base = BASE_B;
            baseUnit = UNIT_BIT;
            break;

        case 1:	// KB
            base = BASE_KB;
            baseUnit = UNIT_KB;
            break;

        case 2:	// MB
            base = BASE_MB;
            baseUnit = UNIT_MB;
            break;

        case 3:	// GB
            base = BASE_GB;
            baseUnit = UNIT_GB;
            break;

        case 4:	// TB
            base = BASE_TB;
            baseUnit = UNIT_TB;
            break;
            
        default:
            break;
        }
        
        BigDecimal filesizeDecimal = new BigDecimal(fileSize);
        BigDecimal baseDecimal = new BigDecimal(base);
        floatSize = filesizeDecimal.divide(baseDecimal, precision, BigDecimal.ROUND_HALF_UP).doubleValue();
        fileSizeStr = Double.toString(floatSize);
        if (precision == 0) {
            indexMid = fileSizeStr.indexOf('.');
            if (-1 == indexMid) {	// 字符串中没有这样的字符
                return fileSizeStr + baseUnit;
            }
            return fileSizeStr.substring(0, indexMid) + baseUnit;
        }

        // baseUnit = UNIT_BIT;
        if (baseUnit.equals(UNIT_BIT)) {
            int pos = fileSizeStr.indexOf('.');
            fileSizeStr = fileSizeStr.substring(0, pos);
        }

        if (baseUnit.equals(UNIT_KB)) {
            int pos = fileSizeStr.indexOf('.');
            if (pos != -1) {
                fileSizeStr = fileSizeStr.substring(0, pos + 2);
            } else {
                fileSizeStr = fileSizeStr + ".0";
            }
        }

        return fileSizeStr + baseUnit;
    }
    
    
    /**
     * 将int32类型的IP地址转换成四个8字节的String类型。
     * 
     * @param addr
     * @return
     */
    public static String ipAddressToString(int addr) {
        StringBuffer buf = new StringBuffer(16);
        buf.append(addr & 0xff).append('.').append((addr >>>= 8) & 0xff).append('.').append((addr >>>= 8) & 0xff)
                .append('.').append((addr >>>= 8) & 0xff);
        return buf.toString();
    }
    
    
    static public int parseInt(String mEpisodeIdStr2) {
        int i, result = 0;
        if (null == mEpisodeIdStr2)
            return 0;
        for (i = 0; i < mEpisodeIdStr2.length(); i++)
            if ((mEpisodeIdStr2.charAt(i) >= '0') && mEpisodeIdStr2.charAt(i) <= '9')
                result = result * 10 + (mEpisodeIdStr2.charAt(i) - '0');
        return result;
    }
    
    public static int Str2Int(String strInt, int defaultValue) {
        if(null == strInt)
            return defaultValue;
        String newStrInt = strInt.trim();
        int result = 0;
        try {
            result = Integer.parseInt(newStrInt);
        } catch(NumberFormatException e) {
            result = defaultValue;
        }
        return result;
    }
    
    public static String byteConvertToSpeed(long byteNum, boolean trim)
    {
        double tmp = byteNum / (1000 * 1024 * 1024 * 1.0);
        double f;
        String res;
        if (tmp >= 1.0)
        {
            // 大于等于1000M 用G表示
            f = byteNum / (1024 * 1024 * 1024 * 1.0);
            BigDecimal b = new BigDecimal(f);
            double doubleRes = b.setScale(2, BigDecimal.ROUND_DOWN)
                    .doubleValue();
            res = Double.toString(doubleRes) + "GB";
        }
        else
        {
            // 小于1000M
            tmp = byteNum / (1000 * 1024 * 1.0);
            if (tmp >= 1.0)
            {
                // 大于等于1000K
                f = byteNum / (1024 * 1024 * 1.0);
                BigDecimal b = new BigDecimal(f);
                double doubleRes = b.setScale(1, BigDecimal.ROUND_DOWN)
                        .doubleValue();
                res = Double.toString(doubleRes) + "MB";
            }
            else
            {
                // 小于1M
                tmp = byteNum / (1000 * 1.0);
                if (tmp >= 1.0)
                {
                    // 大于等于1000B
                    f = byteNum / (1024 * 1.0);
                    BigDecimal b = new BigDecimal(f);
                    double doubleRes = b.setScale(1, BigDecimal.ROUND_DOWN)
                            .doubleValue();
                    res = Double.toString(doubleRes) + "KB";
                }
                else
                {
                    // 小于1000B
                    res = byteNum + "B";
                    trim = false;
                }
            }
        }
        if (trim)
        {
            if (res.length() >= 7)
            {
                String original = res;
                res = original.substring(0, 4);
                if (res.endsWith("."))
                {
                    res = res.substring(0, 3);
                }
                res = res
                        + original.substring(original.length() - 2,
                                original.length());
            }
        }

        return res;
    }
	/**
	 * 将文件最后的修改时间的显示转化为标准显示形式
	 * 
	 * @param mtime
	 *            以毫秒数显示的文件最后修改时间
	 * */
	public static String changeFileTime(long mtime) {
		String result = "";
	//	Log.i(TAG,"settingDateFormat = " + ((mainActivity)GlobalFiled.GLOBAL_CONTEXT).settingDateFormat );
		
		DateFormat tformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		Date tdate = new Date(mtime);
		result = tformat.format(tdate);
		return result;
	}   
    
	/**
	 * 获取大端int型byte数据
	 * @param integer 整形数据
	 * @return
	 */
	public static byte[] toBigEndianBytes(int integer)
	{	
		return IntegerUtils.toBigEndianBytes(integer);
		
	}
	/**
	 * 获取大端int型byte数据
	 * @param integer 整形数据
	 * @param iArrayLen bytes的长度
	 * @return
	 */
	public static byte[] toBigEndianBytes(int integer, int iArrayLen) {
		    return IntegerUtils.toBigEndianBytes(integer, iArrayLen);
	}
	/**
	 * 获取小端int型byte数据
	 * @param integer 整形数据
	 * @return
	 */
	public static byte[] toBytes(int integer)
	{
		return IntegerUtils.toBytes(integer);

	}
	/**
	 * 获取小端int型byte数据
	 * @param integer 整形数据
	 * @param iArrayLen bytes的长度
	 * @return
	 */
	public static byte[] toBytes(int integer,int iArrayLen)
	{
		return IntegerUtils.toBytes(integer, iArrayLen);
	}
	
	/**
	 * 大端byte数组转化成int
	 * @param bytes 大端数组
	 * @return 
	 */
	public static int getIntegerFromBigEndianBytes(byte[] bytes)
	{

	    return IntegerUtils.getIntegerFromBigEndianBytes(bytes);

	}
	/**
	 * 小端byte数据转化成int
	 * @param bytes 小端数组
	 * @return
	 */
	public static int getInteger(byte[] bytes)
	{
		return IntegerUtils.getInteger(bytes);		
	}
    
    
}
